Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions WordPress/Classes/Services/AccountService+SocialService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Foundation
import WordPressComKit

extension AccountService {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love this.


/// Connect an account a social service via an ID token.
///
/// - Parameters:
/// - service The name of the social service.
/// - token The service's OpenID Connect (JWT) ID token for the user.
/// - success
/// - failure
func connectToSocialService(_ service: SocialServiceName, serviceIDToken token:String, success:@escaping (() -> Void), failure:@escaping ((NSError) -> Void)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Colon Violation: Colons should be next to the identifier when specifying a type and next to the key in dictionary literals. (colon)

guard let api = defaultWordPressComAccount()?.wordPressComRestApi,
let remote = AccountServiceRemoteREST(wordPressComRestApi: api) else {
fatalError("Failed to initialize a valid remote via the default WordPress.com account.")
}
remote.connectToSocialService(service, serviceIDToken: token, success: success, failure: failure)
}

/// Disconnect an account a social service via an ID token.
/// - Parameters:
/// - service The name of the social service.
/// - success
/// - failure
func disconnectFromSocialService(_ service: SocialServiceName, success:@escaping (() -> Void), failure:@escaping ((NSError) -> Void)) {
guard let api = defaultWordPressComAccount()?.wordPressComRestApi,
let remote = AccountServiceRemoteREST(wordPressComRestApi: api) else {
fatalError("Failed to initialize a valid remote via the default WordPress.com account.")
}
remote.disconnectFromSocialService(service, success: success, failure: failure)
}

}
21 changes: 21 additions & 0 deletions WordPress/Classes/Services/LoginFacade.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


@class LoginFields;
@class SocialLogin2FANonceInfo;
@protocol WordPressComOAuthClientFacade;
@protocol WordPressXMLRPCAPIFacade;
@protocol LoginFacadeDelegate;
Expand Down Expand Up @@ -43,6 +44,9 @@
*/
- (void)requestOneTimeCodeWithLoginFields:(LoginFields *)loginFields;


- (void)loginToWordPressDotComWithGoogleIDToken:(NSString *)googleIDToken;

/**
* A delegate with a few methods that indicate various aspects of the login process
*/
Expand Down Expand Up @@ -86,6 +90,14 @@
*/
- (void)needsMultifactorCode;

/**
* This is called when the initial login failed because we need a 2fa code for a social login.
*
* @param userID the WPCom userID of the user logging in.
* @param nonceInfo an object containing information about available 2fa nonce options.
*/
- (void)needsMultifactorCodeForUserID:(NSInteger)userID andNonceInfo:(SocialLogin2FANonceInfo *)nonceInfo;

/**
* This is called when there's been an error and we want to inform the user.
*
Expand Down Expand Up @@ -113,5 +125,14 @@
*/
- (void)finishedLoginWithUsername:(NSString *)username authToken:(NSString *)authToken requiredMultifactorCode:(BOOL)requiredMultifactorCode;


/**
* Called when finished logging in to a WordPress.com site via a Google token.
*
* @param googleIDToken the token used
* @param authToken authToken to be used to access the site
*/
- (void)finishedLoginWithGoogleIDToken:(NSString *)googleIDToken authToken:(NSString *)authToken;

@end

24 changes: 22 additions & 2 deletions WordPress/Classes/Services/LoginFacade.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ - (void)signInWithLoginFields:(LoginFields *)loginFields
}
}


- (void)loginWithLoginFields:(LoginFields *)loginFields
{
NSAssert(self.delegate != nil, @"Must set delegate to use service");
Expand All @@ -52,7 +51,6 @@ - (void)loginWithLoginFields:(LoginFields *)loginFields
}
}


- (void)requestOneTimeCodeWithLoginFields:(LoginFields *)loginFields
{
[self.wordpressComOAuthClientFacade requestOneTimeCodeWithUsername:loginFields.username password:loginFields.password success:^{
Expand All @@ -62,6 +60,28 @@ - (void)requestOneTimeCodeWithLoginFields:(LoginFields *)loginFields
}];
}

- (void)loginToWordPressDotComWithGoogleIDToken:(NSString *)googleIDToken
{
if ([self.delegate respondsToSelector:@selector(displayLoginMessage:)]) {
[self.delegate displayLoginMessage:NSLocalizedString(@"Connecting to WordPress.com", nil)];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we already do this in -signInToWordpressDotCom but I don't really love having UI-surfaced strings in the networking code. If instead we told the delegate the state had changed, the VC could decide how to present it: string, icon, or otherwise. Think that's worth changing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too much of a fan either. I still have the dream of nuking the facade completely, but until then I think we should be consistent.

}

[self.wordpressComOAuthClientFacade authenticateWithGoogleIDToken:googleIDToken success:^(NSString *authToken) {
if ([self.delegate respondsToSelector:@selector(finishedLoginWithGoogleIDToken:authToken:)]) {
[self.delegate finishedLoginWithGoogleIDToken:googleIDToken authToken:authToken];
}
} needsMultiFactor:^(NSInteger userID, SocialLogin2FANonceInfo *nonceInfo){
if ([self.delegate respondsToSelector:@selector(needsMultifactorCodeForUserID:andNonceInfo:)]) {
[self.delegate needsMultifactorCodeForUserID:userID andNonceInfo:nonceInfo];
}
} failure:^(NSError *error) {
[WPAppAnalytics track:WPAnalyticsStatLoginFailed error:error];
if ([self.delegate respondsToSelector:@selector(displayRemoteError:)]) {
[self.delegate displayRemoteError:error];
}
}];
}

- (void)signInToWordpressDotCom:(LoginFields *)loginFields
{
if ([self.delegate respondsToSelector:@selector(displayLoginMessage:)]) {
Expand Down
12 changes: 12 additions & 0 deletions WordPress/Classes/Services/WordPressComOAuthClientFacade.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#import <Foundation/Foundation.h>

@class SocialLogin2FANonceInfo;
@protocol WordPressComOAuthClientFacade


Expand All @@ -15,6 +16,17 @@
success:(void (^)(void))success
failure:(void (^)(NSError *error))failure;

- (void)authenticateWithGoogleIDToken:(NSString *)token
success:(void (^)(NSString *authToken))success
needsMultiFactor:(void (^)(NSInteger userID, SocialLogin2FANonceInfo *nonceInfo))needsMultifactor
failure:(void (^)(NSError *error))failure;

- (void)authenticateSocialLoginUser:(NSInteger)userID
authType:(NSString *)authType
twoStepCode:(NSString *)twoStepCode
twoStepNonce:(NSString *)twoStepNonce
success:(void (^)(NSString *authToken))success
failure:(void (^)(NSError *error))failure;
@end

@interface WordPressComOAuthClientFacade : NSObject <WordPressComOAuthClientFacade>
Expand Down
20 changes: 20 additions & 0 deletions WordPress/Classes/Services/WordPressComOAuthClientFacade.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,24 @@ - (void)requestOneTimeCodeWithUsername:(NSString *)username
[client requestOneTimeCodeWithUsername:username password:password success:success failure:failure];
}

- (void)authenticateWithGoogleIDToken:(NSString *)token
success:(void (^)(NSString *authToken))success
needsMultiFactor:(void (^)(NSInteger userID, SocialLogin2FANonceInfo *nonceInfo))needsMultifactor
failure:(void (^)(NSError *error))failure
{
WordPressComOAuthClient *client = [WordPressComOAuthClient clientWithClientID:ApiCredentials.client secret:ApiCredentials.secret];
[client authenticateWithIDToken:token success:success needsMultifactor:needsMultifactor failure:failure];
}

- (void)authenticateSocialLoginUser:(NSInteger)userID
authType:(NSString *)authType
twoStepCode:(NSString *)twoStepCode
twoStepNonce:(NSString *)twoStepNonce
success:(void (^)(NSString *authToken))success
failure:(void (^)(NSError *error))failure
{
WordPressComOAuthClient *client = [WordPressComOAuthClient clientWithClientID:ApiCredentials.client secret:ApiCredentials.secret];
[client authenticateSocialLoginUser:userID authType:authType twoStepCode:twoStepCode twoStepNonce:twoStepNonce success:success failure:failure];
}

@end
45 changes: 36 additions & 9 deletions WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class LoginEmailViewController: LoginViewController, SigninKeyboardResponder {
@IBOutlet var bottomContentConstraint: NSLayoutConstraint?
@IBOutlet var verticalCenterConstraint: NSLayoutConstraint?
var onePasswordButton: UIButton!
var googleLoginButton: UIButton?

var didFindSafariSharedCredentials = false
var didRequestSafariSharedCredentials = false
Expand Down Expand Up @@ -124,7 +125,8 @@ class LoginEmailViewController: LoginViewController, SigninKeyboardResponder {

/// Add the log in with Google button to the view
func addGoogleButton() {
guard Feature.enabled(.googleLogin) else {
guard Feature.enabled(.googleLogin),
let instructionLabel = instructionLabel else {
return
}

Expand All @@ -134,10 +136,11 @@ class LoginEmailViewController: LoginViewController, SigninKeyboardResponder {

view.addConstraints([
button.topAnchor.constraint(equalTo: self.emailTextField.bottomAnchor, constant: Constants.googleButtonOffset),
button.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
button.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
button.leadingAnchor.constraint(equalTo: instructionLabel.leadingAnchor),
button.trailingAnchor.constraint(equalTo:instructionLabel.trailingAnchor),
button.centerXAnchor.constraint(equalTo: emailTextField.centerXAnchor)
])
googleLoginButton = button
}

func googleLoginTapped() {
Expand Down Expand Up @@ -172,6 +175,8 @@ class LoginEmailViewController: LoginViewController, SigninKeyboardResponder {
///
override func configureViewLoading(_ loading: Bool) {
emailTextField.isEnabled = !loading
googleLoginButton?.isEnabled = !loading

submitButton?.isEnabled = !loading
submitButton?.showActivityIndicator(loading)
}
Expand Down Expand Up @@ -370,15 +375,37 @@ class LoginEmailViewController: LoginViewController, SigninKeyboardResponder {

}

// LoginFacadeDelegate methods for Google Google Sign In
extension LoginEmailViewController {
func finishedLogin(withGoogleIDToken googleIDToken: String!, authToken: String!) {
let username = loginFields.username
syncWPCom(username, authToken: authToken, requiredMultifactor: false)
}

func needsMultifactorCode(forUserID userID: Int, andNonceInfo nonceInfo: SocialLogin2FANonceInfo!) {
// TODO: to be implemented.
}
}

extension LoginEmailViewController: GIDSignInDelegate {
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
// TODO: implement wpcom login via Google code
// TODO: finish implementing wpcom login via Google code
guard let token = user.authentication.idToken,
let email = user.profile.email else {
// The Google SignIn for may have been canceled.
//TODO: Add analytis
return
}

// Store the email address.
loginFields.emailAddress = email
loginFields.username = email

configureViewLoading(true)

loginFacade.loginToWordPressDotCom(withGoogleIDToken: token)

let alert = UIAlertController(title: "Login Success", message: "Google login succeeded. Actual wpcom account login yet to be implemented.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok. Thanks.", style: .default, handler: { [weak self] (action) in
self?.dismiss(animated: true) {}
}))
present(alert, animated: true)
//TODO: Add analytis
}
}

Expand Down
18 changes: 11 additions & 7 deletions WordPress/WordPress.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,7 @@
E6C448571CB091AA00458157 /* SigninKeyboardResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6C448561CB091AA00458157 /* SigninKeyboardResponder.swift */; };
E6C892D61C601D55007AD612 /* SharingButtonsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6C892D51C601D55007AD612 /* SharingButtonsViewController.swift */; };
E6D0088E1EF0880C009E5FA3 /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6D0088D1EF0880C009E5FA3 /* LoginViewController.swift */; };
E6D0EE601F7EF9830064D3FC /* AccountService+SocialService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6D0EE5F1F7EF9830064D3FC /* AccountService+SocialService.swift */; };
E6D170371EF9D8D10046D433 /* SiteInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6D170361EF9D8D10046D433 /* SiteInfo.swift */; };
E6D2E15F1B8A9C830000ED14 /* ReaderSiteStreamHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = E6D2E15E1B8A9C830000ED14 /* ReaderSiteStreamHeader.xib */; };
E6D2E1611B8AA4410000ED14 /* ReaderTagStreamHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = E6D2E1601B8AA4410000ED14 /* ReaderTagStreamHeader.xib */; };
Expand Down Expand Up @@ -2322,6 +2323,7 @@
E6C448561CB091AA00458157 /* SigninKeyboardResponder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SigninKeyboardResponder.swift; sourceTree = "<group>"; };
E6C892D51C601D55007AD612 /* SharingButtonsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharingButtonsViewController.swift; sourceTree = "<group>"; };
E6D0088D1EF0880C009E5FA3 /* LoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = "<group>"; };
E6D0EE5F1F7EF9830064D3FC /* AccountService+SocialService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AccountService+SocialService.swift"; sourceTree = "<group>"; };
E6D170361EF9D8D10046D433 /* SiteInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SiteInfo.swift; sourceTree = "<group>"; };
E6D2E15E1B8A9C830000ED14 /* ReaderSiteStreamHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ReaderSiteStreamHeader.xib; sourceTree = "<group>"; };
E6D2E1601B8AA4410000ED14 /* ReaderTagStreamHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ReaderTagStreamHeader.xib; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2778,7 +2780,7 @@
name = Products;
sourceTree = "<group>";
};
29B97314FDCFA39411CA2CEA = {
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
isa = PBXGroup;
children = (
E1B34C091CCDFFCE00889709 /* Credentials */,
Expand Down Expand Up @@ -3694,6 +3696,7 @@
B5EFB1C31B31B99D007608A3 /* Facades */,
93C1147D18EC5DD500DAC95C /* AccountService.h */,
93C1147E18EC5DD500DAC95C /* AccountService.m */,
E6D0EE5F1F7EF9830064D3FC /* AccountService+SocialService.swift */,
E1FD45DF1C030B3800750F4C /* AccountSettingsService.swift */,
822D60B81F4CCC7A0016C46D /* BlogJetpackSettingsService.swift */,
93C1148318EDF6E100DAC95C /* BlogService.h */,
Expand Down Expand Up @@ -5485,7 +5488,7 @@
bg,
sk,
);
mainGroup = 29B97314FDCFA39411CA2CEA;
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
productRefGroup = 19C28FACFE9D520D11CA2CBB /* Products */;
projectDirPath = "";
projectRoot = "";
Expand Down Expand Up @@ -5801,7 +5804,7 @@
inputPaths = (
"${SRCROOT}/../Pods/Target Support Files/Pods-WordPress/Pods-WordPress-resources.sh",
"${PODS_ROOT}/GoogleSignIn/Resources/GoogleSignIn.bundle",
"$PODS_CONFIGURATION_BUILD_DIR/HockeySDK/HockeySDKResources.bundle",
$PODS_CONFIGURATION_BUILD_DIR/HockeySDK/HockeySDKResources.bundle,
);
name = "[CP] Copy Pods Resources";
outputPaths = (
Expand Down Expand Up @@ -6170,6 +6173,7 @@
85D239B61AE5A6170074768D /* ReachabilityFacade.m in Sources */,
E6D3B1431D1C702600008D4B /* ReaderFollowedSitesViewController.swift in Sources */,
B5899ADE1B419C560075A3D6 /* NotificationSettingDetailsViewController.swift in Sources */,
E6D0EE601F7EF9830064D3FC /* AccountService+SocialService.swift in Sources */,
FAE4201A1C5AEFE100C1D036 /* StartOverViewController.swift in Sources */,
B57B99D519A2C20200506504 /* NoteTableHeaderView.swift in Sources */,
1790A4531E28F0ED00AE54C2 /* UINavigationController+Helpers.swift in Sources */,
Expand Down Expand Up @@ -7064,7 +7068,7 @@
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
WPCOM_CONFIG = "$HOME/.wpcom_app_credentials";
WPCOM_CONFIG = $HOME/.wpcom_app_credentials;
WPCOM_SCHEME = wpdebug;
};
name = Debug;
Expand Down Expand Up @@ -7130,7 +7134,7 @@
SWIFT_OBJC_BRIDGING_HEADER = "Classes/System/WordPress-Bridging-Header.h";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
WPCOM_CONFIG = "$HOME/.wpcom_app_credentials";
WPCOM_CONFIG = $HOME/.wpcom_app_credentials;
WPCOM_SCHEME = wordpress;
};
name = Release;
Expand Down Expand Up @@ -7417,7 +7421,7 @@
SWIFT_OBJC_BRIDGING_HEADER = "Classes/System/WordPress-Bridging-Header.h";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
WPCOM_CONFIG = "$HOME/.wpcom_alpha_app_credentials";
WPCOM_CONFIG = $HOME/.wpcom_alpha_app_credentials;
WPCOM_SCHEME = wpalpha;
};
name = "Release-Alpha";
Expand Down Expand Up @@ -7845,7 +7849,7 @@
SWIFT_OBJC_BRIDGING_HEADER = "Classes/System/WordPress-Bridging-Header.h";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
WPCOM_CONFIG = "$HOME/.wpcom_internal_app_credentials";
WPCOM_CONFIG = $HOME/.wpcom_internal_app_credentials;
WPCOM_SCHEME = wpinternal;
};
name = "Release-Internal";
Expand Down
Loading