Skip to content
This repository was archived by the owner on Feb 5, 2025. It is now read-only.

Commit 47e1aef

Browse files
authored
Replace AppleUser with SocialService.User (#763)
2 parents b4af009 + 2fd983a commit 47e1aef

File tree

10 files changed

+383
-80
lines changed

10 files changed

+383
-80
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ _None._
3434

3535
### Breaking Changes
3636

37-
_None._
37+
- `SocialService` `apple` associated type is now `User` instead of `AppleUser`. [#763]
3838

3939
### New Features
4040

WordPressAuthenticator.xcodeproj/project.pbxproj

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
3F82E63929931D95003EFC16 /* CodeVerifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F82E63829931D95003EFC16 /* CodeVerifierTests.swift */; };
3434
3F82E63B29935E12003EFC16 /* Data+SHA256.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F82E63A29935E12003EFC16 /* Data+SHA256.swift */; };
3535
3F82E63D29935E65003EFC16 /* Data+SHA256Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F82E63C29935E65003EFC16 /* Data+SHA256Tests.swift */; };
36+
3F86A83E29D280D7005D20C0 /* AppleAuthenticatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F86A83D29D280D7005D20C0 /* AppleAuthenticatorTests.swift */; };
37+
3F86A84229D28473005D20C0 /* SocialUserCreating.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F86A84129D28473005D20C0 /* SocialUserCreating.swift */; };
38+
3F86A84629D2A306005D20C0 /* WordPressAuthenticatorDelegateSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F86A84529D2A306005D20C0 /* WordPressAuthenticatorDelegateSpy.swift */; };
39+
3F86A84829D2A42D005D20C0 /* WordPressAuthenticator+TestsUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F86A84729D2A42D005D20C0 /* WordPressAuthenticator+TestsUtils.swift */; };
3640
3F879FD5293A3AB6005C2B48 /* OAuthTokenRequestBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F879FD4293A3AB6005C2B48 /* OAuthTokenRequestBody.swift */; };
3741
3F879FD7293A44F2005C2B48 /* OAuthTokenRequestBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F879FD6293A44F2005C2B48 /* OAuthTokenRequestBodyTests.swift */; };
3842
3F879FD9293A48B2005C2B48 /* OAuthTokenResponseBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F879FD8293A48B2005C2B48 /* OAuthTokenResponseBody.swift */; };
@@ -284,6 +288,10 @@
284288
3F82E63829931D95003EFC16 /* CodeVerifierTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeVerifierTests.swift; sourceTree = "<group>"; };
285289
3F82E63A29935E12003EFC16 /* Data+SHA256.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+SHA256.swift"; sourceTree = "<group>"; };
286290
3F82E63C29935E65003EFC16 /* Data+SHA256Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+SHA256Tests.swift"; sourceTree = "<group>"; };
291+
3F86A83D29D280D7005D20C0 /* AppleAuthenticatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleAuthenticatorTests.swift; sourceTree = "<group>"; };
292+
3F86A84129D28473005D20C0 /* SocialUserCreating.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocialUserCreating.swift; sourceTree = "<group>"; };
293+
3F86A84529D2A306005D20C0 /* WordPressAuthenticatorDelegateSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordPressAuthenticatorDelegateSpy.swift; sourceTree = "<group>"; };
294+
3F86A84729D2A42D005D20C0 /* WordPressAuthenticator+TestsUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WordPressAuthenticator+TestsUtils.swift"; sourceTree = "<group>"; };
287295
3F879FD4293A3AB6005C2B48 /* OAuthTokenRequestBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OAuthTokenRequestBody.swift; sourceTree = "<group>"; };
288296
3F879FD6293A44F2005C2B48 /* OAuthTokenRequestBodyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OAuthTokenRequestBodyTests.swift; sourceTree = "<group>"; };
289297
3F879FD8293A48B2005C2B48 /* OAuthTokenResponseBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OAuthTokenResponseBody.swift; sourceTree = "<group>"; };
@@ -545,6 +553,14 @@
545553
path = "Email Client Picker";
546554
sourceTree = "<group>";
547555
};
556+
3F86A83F29D280DC005D20C0 /* SingIn */ = {
557+
isa = PBXGroup;
558+
children = (
559+
3F86A83D29D280D7005D20C0 /* AppleAuthenticatorTests.swift */,
560+
);
561+
path = SingIn;
562+
sourceTree = "<group>";
563+
};
548564
3FE8072229365F740088420C /* GoogleSignIn */ = {
549565
isa = PBXGroup;
550566
children = (
@@ -686,8 +702,9 @@
686702
isa = PBXGroup;
687703
children = (
688704
3108613025AFA4830022F75E /* PasteboardTests.swift */,
689-
B501C03E208FC52500D1E58F /* WordPressAuthenticatorTests.swift */,
705+
3F86A84729D2A42D005D20C0 /* WordPressAuthenticator+TestsUtils.swift */,
690706
CE16177721B70C1A00B82A47 /* WordPressAuthenticatorDisplayTextTests.swift */,
707+
B501C03E208FC52500D1E58F /* WordPressAuthenticatorTests.swift */,
691708
BA53D64724DFDF97001F1ABF /* WordPressSourceTagTests.swift */,
692709
);
693710
path = Authenticator;
@@ -815,6 +832,7 @@
815832
B5609104208A54F800399AE4 /* SafariCredentialsService.swift */,
816833
B56090FE208A54F700399AE4 /* SignupService.swift */,
817834
CE1B18C820EEC2C200BECC3F /* SocialService.swift */,
835+
3F86A84129D28473005D20C0 /* SocialUserCreating.swift */,
818836
B56090FF208A54F800399AE4 /* WordPressComAccountService.swift */,
819837
B56090FC208A54F700399AE4 /* WordPressComBlogService.swift */,
820838
B56090FD208A54F700399AE4 /* WordPressComOAuthClientFacade.h */,
@@ -929,6 +947,7 @@
929947
B501C03B208FC52400D1E58F /* Model */,
930948
D85C36E4256E0DAF00D56E34 /* Navigation */,
931949
B501C03F208FC52500D1E58F /* Services */,
950+
3F86A83F29D280DC005D20C0 /* SingIn */,
932951
F18DF0E32525009200D83AFE /* SupportingFiles */,
933952
3F338B6B289B87E60014ADC5 /* UnitTests.xctestplan */,
934953
);
@@ -968,9 +987,10 @@
968987
BA53D64924DFE06C001F1ABF /* Mocks */ = {
969988
isa = PBXGroup;
970989
children = (
990+
D85C36EB256E10EA00D56E34 /* MockNavigationController.swift */,
971991
BA53D64C24DFE4E6001F1ABF /* ModalViewControllerPresentingSpy.swift */,
992+
3F86A84529D2A306005D20C0 /* WordPressAuthenticatorDelegateSpy.swift */,
972993
BA53D64A24DFE07D001F1ABF /* WordpressAuthenticatorProvider.swift */,
973-
D85C36EB256E10EA00D56E34 /* MockNavigationController.swift */,
974994
);
975995
path = Mocks;
976996
sourceTree = "<group>";
@@ -1504,6 +1524,7 @@
15041524
CE9C5B4E24E31E03005A8BCF /* SignupMagicLinkViewController.swift in Sources */,
15051525
B56090E4208A4F9D00399AE4 /* WPNUXMainButton.m in Sources */,
15061526
3FFF2FC323D7F53200D38C77 /* AppSelector.swift in Sources */,
1527+
3F86A84229D28473005D20C0 /* SocialUserCreating.swift in Sources */,
15071528
3F9439BE27D6F9B60067183A /* LoginPrologueViewController.swift in Sources */,
15081529
B560913B208A563800399AE4 /* LoginSelfHostedViewController.swift in Sources */,
15091530
B5609136208A563800399AE4 /* Login2FAViewController.swift in Sources */,
@@ -1533,6 +1554,7 @@
15331554
BA53D64824DFDF97001F1ABF /* WordPressSourceTagTests.swift in Sources */,
15341555
3F30A6BA299F12E30004452F /* Character+URLSafeTests.swift in Sources */,
15351556
4A1DEF4B29341B1F00322608 /* LoggingTests.swift in Sources */,
1557+
3F86A83E29D280D7005D20C0 /* AppleAuthenticatorTests.swift in Sources */,
15361558
3F3694022991E244006E923E /* JSONWebToken+Fixtures.swift in Sources */,
15371559
3F879FDF293A501D005C2B48 /* URLRequest+GoogleSignInTests.swift in Sources */,
15381560
D8610CEC2570A60C00A5DF27 /* NavigationToRootTests.swift in Sources */,
@@ -1547,13 +1569,15 @@
15471569
3FEC44F9293A0F2900EBDECF /* ProofKeyForCodeExchangeTests.swift in Sources */,
15481570
3F107B0529A87AF0009B3658 /* CodeVerifier+Fixture.swift in Sources */,
15491571
CE16177821B70C1A00B82A47 /* WordPressAuthenticatorDisplayTextTests.swift in Sources */,
1572+
3F86A84829D2A42D005D20C0 /* WordPressAuthenticator+TestsUtils.swift in Sources */,
15501573
3F879FF4293A7F46005C2B48 /* GoogleOAuthTokenGetterTests.swift in Sources */,
15511574
B501C048208FC79C00D1E58F /* LoginFacadeTests.m in Sources */,
15521575
3F879FD7293A44F2005C2B48 /* OAuthTokenRequestBodyTests.swift in Sources */,
15531576
3108613125AFA4830022F75E /* PasteboardTests.swift in Sources */,
15541577
3FE8071F2936558F0088420C /* URL+GoogleSignInTests.swift in Sources */,
15551578
D85C36F0256E118D00D56E34 /* NavigationToEnterAccountTests.swift in Sources */,
15561579
D85C36E6256E0DDE00D56E34 /* NavigationToEnterSiteTests.swift in Sources */,
1580+
3F86A84629D2A306005D20C0 /* WordPressAuthenticatorDelegateSpy.swift in Sources */,
15571581
D85C3882256E3FEC00D56E34 /* WordPressComSiteInfoTests.swift in Sources */,
15581582
D8611A672576236800A5DF27 /* NavigateBackTests.swift in Sources */,
15591583
3F879FF8293E222E005C2B48 /* GoogleOAuthTokenGettingStub.swift in Sources */,

WordPressAuthenticator/Model/LoginFields.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public class LoginFieldsMeta: NSObject {
154154

155155
var googleUser: GIDGoogleUser?
156156

157-
var appleUser: AppleUser?
157+
var appleUser: SocialService.User?
158158

159159
init(emailMagicLinkSource: EmailMagicLinkSource? = nil,
160160
jetpackLogin: Bool = false,
@@ -166,7 +166,7 @@ public class LoginFieldsMeta: NSObject {
166166
socialService: SocialServiceName? = nil,
167167
socialServiceIDToken: String? = nil,
168168
googleUser: GIDGoogleUser? = nil,
169-
appleUser: AppleUser? = nil) {
169+
appleUser: SocialService.User? = nil) {
170170
self.emailMagicLinkSource = emailMagicLinkSource
171171
self.jetpackLogin = jetpackLogin
172172
self.userIsDotCom = userIsDotCom

WordPressAuthenticator/Services/SignupService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import WordPressKit
44

55
/// SignupService: Responsible for creating a new WPCom user and blog.
66
///
7-
class SignupService {
7+
class SignupService: SocialUserCreating {
88

99
/// Create a new WPcom account using Google signin token
1010
///

WordPressAuthenticator/Services/SocialService.swift

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@ import GoogleSignIn
44
//
55
public enum SocialService {
66

7+
public struct User {
8+
public let email: String
9+
public let fullName: String
10+
}
11+
712
/// Google's Signup Linked Account
813
///
914
case google(user: GIDGoogleUser)
1015

1116
/// Apple's Signup Linked Account
1217
///
13-
case apple(user: AppleUser)
14-
}
15-
16-
// Struct to contain information relevant to an Apple ID account.
17-
public struct AppleUser {
18-
public var email: String
19-
public var fullName: String
18+
case apple(user: User)
2019
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/// A type that can create WordPress.com users given a social users, either coming from Google or Apple.
2+
protocol SocialUserCreating: AnyObject {
3+
4+
func createWPComUserWithGoogle(
5+
token: String,
6+
success: @escaping (_ newAccount: Bool, _ username: String, _ wpcomToken: String) -> Void,
7+
failure: @escaping (_ error: Error) -> Void
8+
)
9+
10+
func createWPComUserWithApple(
11+
token: String,
12+
email: String,
13+
fullName: String?,
14+
success: @escaping (
15+
_ newAccount: Bool,
16+
_ existingNonSocialAccount: Bool,
17+
_ existing2faAccount: Bool,
18+
_ username: String,
19+
_ wpcomToken: String
20+
) -> Void,
21+
failure: @escaping (_ error: Error) -> Void
22+
)
23+
}

WordPressAuthenticator/Signin/AppleAuthenticator.swift

Lines changed: 90 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,15 @@ class AppleAuthenticator: NSObject {
1414
// MARK: - Properties
1515

1616
static var sharedInstance: AppleAuthenticator = AppleAuthenticator()
17-
private override init() {}
1817
private var showFromViewController: UIViewController?
1918
private let loginFields = LoginFields()
2019
weak var delegate: AppleAuthenticatorDelegate?
20+
let signupService: SocialUserCreating
21+
22+
init(signupService: SocialUserCreating = SignupService()) {
23+
self.signupService = signupService
24+
super.init()
25+
}
2126

2227
static let credentialRevokedNotification = ASAuthorizationAppleIDProvider.credentialRevokedNotification
2328

@@ -76,59 +81,12 @@ private extension AppleAuthenticator {
7681
return
7782
}
7883

79-
tracker.set(flow: .signupWithApple)
80-
tracker.track(step: .start) {
81-
track(.createAccountInitiated)
82-
}
83-
84-
SVProgressHUD.show(withStatus: NSLocalizedString("Continuing with Apple", comment: "Shown while logging in with Apple and the app waits for the site creation process to complete."))
85-
86-
let email = appleCredentials.email ?? ""
87-
let name = fullName(from: appleCredentials.fullName)
88-
89-
updateLoginFields(email: email, fullName: name, token: token)
90-
91-
let service = SignupService()
92-
service.createWPComUserWithApple(token: token, email: email, fullName: name,
93-
success: { [weak self] accountCreated,
94-
existingNonSocialAccount,
95-
existing2faAccount,
96-
wpcomUsername,
97-
wpcomToken in
98-
SVProgressHUD.dismiss()
99-
100-
// Notify host app of successful Apple authentication
101-
self?.authenticationDelegate.userAuthenticatedWithAppleUserID(appleCredentials.user)
102-
103-
guard !existingNonSocialAccount else {
104-
self?.tracker.set(flow: .loginWithApple)
105-
106-
if existing2faAccount {
107-
self?.show2FA()
108-
return
109-
}
110-
111-
self?.updateLoginEmail(wpcomUsername)
112-
self?.logInInstead()
113-
return
114-
}
115-
116-
let wpcom = WordPressComCredentials(authToken: wpcomToken, isJetpackLogin: false, multifactor: false, siteURL: self?.loginFields.siteAddress ?? "")
117-
let credentials = AuthenticatorCredentials(wpcom: wpcom)
118-
119-
if accountCreated {
120-
self?.authenticationDelegate.createdWordPressComAccount(username: wpcomUsername, authToken: wpcomToken)
121-
self?.signupSuccessful(with: credentials)
122-
} else {
123-
self?.authenticationDelegate.sync(credentials: credentials) {
124-
self?.loginSuccessful(with: credentials)
125-
}
126-
}
127-
128-
}, failure: { [weak self] error in
129-
SVProgressHUD.dismiss()
130-
self?.signupFailed(with: error)
131-
})
84+
createWordPressComUser(
85+
appleUserId: appleCredentials.user,
86+
email: appleCredentials.email ?? "",
87+
name: fullName(from: appleCredentials.fullName),
88+
token: token
89+
)
13290
}
13391

13492
func signupSuccessful(with credentials: AuthenticatorCredentials) {
@@ -155,18 +113,6 @@ private extension AppleAuthenticator {
155113
showLoginEpilogue(for: credentials)
156114
}
157115

158-
func showSignupEpilogue(for credentials: AuthenticatorCredentials) {
159-
guard let navigationController = showFromViewController?.navigationController else {
160-
fatalError()
161-
}
162-
163-
let service = loginFields.meta.appleUser.flatMap {
164-
return SocialService.apple(user: $0)
165-
}
166-
167-
authenticationDelegate.presentSignupEpilogue(in: navigationController, for: credentials, service: service)
168-
}
169-
170116
func showLoginEpilogue(for credentials: AuthenticatorCredentials) {
171117
guard let navigationController = showFromViewController?.navigationController else {
172118
fatalError()
@@ -220,7 +166,7 @@ private extension AppleAuthenticator {
220166
func updateLoginFields(email: String, fullName: String, token: String) {
221167
updateLoginEmail(email)
222168
loginFields.meta.socialServiceIDToken = token
223-
loginFields.meta.appleUser = AppleUser(email: email, fullName: fullName)
169+
loginFields.meta.appleUser = SocialService.User(email: email, fullName: fullName)
224170
}
225171

226172
func updateLoginEmail(_ email: String) {
@@ -267,3 +213,80 @@ extension AppleAuthenticator {
267213
ASAuthorizationAppleIDProvider().getCredentialState(forUserID: userID, completion: completion)
268214
}
269215
}
216+
217+
// This needs to be internal, at this point in time, to allow testing.
218+
//
219+
// Notice that none of this code was previously tested. A small encapsulation breach like this is
220+
// worth the testability we gain from it.
221+
extension AppleAuthenticator {
222+
223+
func showSignupEpilogue(for credentials: AuthenticatorCredentials) {
224+
guard let navigationController = showFromViewController?.navigationController else {
225+
fatalError()
226+
}
227+
228+
let service = loginFields.meta.appleUser.map {
229+
SocialService.apple(user: $0)
230+
}
231+
232+
authenticationDelegate.presentSignupEpilogue(in: navigationController, for: credentials, service: service)
233+
}
234+
235+
func createWordPressComUser(appleUserId: String, email: String, name: String, token: String) {
236+
tracker.set(flow: .signupWithApple)
237+
tracker.track(step: .start) {
238+
track(.createAccountInitiated)
239+
}
240+
241+
SVProgressHUD.show(
242+
withStatus: NSLocalizedString(
243+
"Continuing with Apple",
244+
comment: "Shown while logging in with Apple and the app waits for the site creation process to complete."
245+
)
246+
)
247+
248+
updateLoginFields(email: email, fullName: name, token: token)
249+
250+
signupService.createWPComUserWithApple(
251+
token: token,
252+
email: email,
253+
fullName: name,
254+
success: { [weak self] accountCreated, existingNonSocialAccount, existing2faAccount, wpcomUsername, wpcomToken in
255+
SVProgressHUD.dismiss()
256+
257+
// Notify host app of successful Apple authentication
258+
self?.authenticationDelegate.userAuthenticatedWithAppleUserID(appleUserId)
259+
260+
guard !existingNonSocialAccount else {
261+
self?.tracker.set(flow: .loginWithApple)
262+
263+
if existing2faAccount {
264+
self?.show2FA()
265+
return
266+
}
267+
268+
self?.updateLoginEmail(wpcomUsername)
269+
self?.logInInstead()
270+
return
271+
}
272+
273+
let wpcom = WordPressComCredentials(authToken: wpcomToken, isJetpackLogin: false, multifactor: false, siteURL: self?.loginFields.siteAddress ?? "")
274+
let credentials = AuthenticatorCredentials(wpcom: wpcom)
275+
276+
if accountCreated {
277+
self?.authenticationDelegate.createdWordPressComAccount(username: wpcomUsername, authToken: wpcomToken)
278+
self?.signupSuccessful(with: credentials)
279+
} else {
280+
self?.authenticationDelegate.sync(credentials: credentials) {
281+
self?.loginSuccessful(with: credentials)
282+
}
283+
}
284+
285+
},
286+
failure: { [weak self] error in
287+
SVProgressHUD.dismiss()
288+
self?.signupFailed(with: error)
289+
}
290+
)
291+
}
292+
}

0 commit comments

Comments
 (0)