diff --git a/MASFoundation.xcodeproj/project.pbxproj b/MASFoundation.xcodeproj/project.pbxproj index c4357fe1..1d0d2b70 100644 --- a/MASFoundation.xcodeproj/project.pbxproj +++ b/MASFoundation.xcodeproj/project.pbxproj @@ -146,8 +146,7 @@ A898EF682182D35700CF291B /* MASJWKSet.m in Sources */ = {isa = PBXBuildFile; fileRef = A898EF662182D35700CF291B /* MASJWKSet.m */; }; A898EF6B2182D3DF00CF291B /* NSURLSession+MASPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A898EF692182D3DF00CF291B /* NSURLSession+MASPrivate.h */; }; A898EF6C2182D3DF00CF291B /* NSURLSession+MASPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = A898EF6A2182D3DF00CF291B /* NSURLSession+MASPrivate.m */; }; - C81CC3CC1FC2EA190058718E /* MASBrowserBasedAuthentication.h in Headers */ = {isa = PBXBuildFile; fileRef = C81CC3CA1FC2EA190058718E /* MASBrowserBasedAuthentication.h */; }; - C81CC3CD1FC2EA190058718E /* MASBrowserBasedAuthentication.m in Sources */ = {isa = PBXBuildFile; fileRef = C81CC3CB1FC2EA190058718E /* MASBrowserBasedAuthentication.m */; }; + C81CC3CC1FC2EA190058718E /* MASBrowserBasedAuthentication.h in Headers */ = {isa = PBXBuildFile; fileRef = C81CC3CA1FC2EA190058718E /* MASBrowserBasedAuthentication.h */; settings = {ATTRIBUTES = (Public, ); }; }; C81CC3D01FC2EFBB0058718E /* UIAlertController+MAS.h in Headers */ = {isa = PBXBuildFile; fileRef = C81CC3CE1FC2EFBB0058718E /* UIAlertController+MAS.h */; }; C81CC3D11FC2EFBB0058718E /* UIAlertController+MAS.m in Sources */ = {isa = PBXBuildFile; fileRef = C81CC3CF1FC2EFBB0058718E /* UIAlertController+MAS.m */; }; C858D6B52398FC5400963763 /* MASDataTask+MASPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = C858D6B32398FC5400963763 /* MASDataTask+MASPrivate.h */; }; @@ -327,6 +326,14 @@ CBD25B151E7A0A9200DFB47F /* MF_Base64Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = CBD25B131E7A0A9200DFB47F /* MF_Base64Additions.m */; }; CBFA70F41F1ED5D6006D025D /* MASSecurityPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = CBFA70F21F1ED5D6006D025D /* MASSecurityPolicy.h */; }; CBFA70F51F1ED5D6006D025D /* MASSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = CBFA70F31F1ED5D6006D025D /* MASSecurityPolicy.m */; }; + E0BA784D257E7FEF0003A9B8 /* MASSafariBrowserBasedAuthentication.m in Sources */ = {isa = PBXBuildFile; fileRef = E0BA784B257E7FEF0003A9B8 /* MASSafariBrowserBasedAuthentication.m */; }; + E0BA7861257EB8C00003A9B8 /* MASWebSessionBrowserBasedAuthentication.m in Sources */ = {isa = PBXBuildFile; fileRef = E0BA785F257EB8C00003A9B8 /* MASWebSessionBrowserBasedAuthentication.m */; }; + E0BA7867257F62570003A9B8 /* MASSafariBrowserBasedAuthentication.h in Headers */ = {isa = PBXBuildFile; fileRef = E0BA784A257E7FEF0003A9B8 /* MASSafariBrowserBasedAuthentication.h */; }; + E0BA7869257F62590003A9B8 /* MASWebSessionBrowserBasedAuthentication.h in Headers */ = {isa = PBXBuildFile; fileRef = E0BA785E257EB8C00003A9B8 /* MASWebSessionBrowserBasedAuthentication.h */; }; + E0BA786D257F62820003A9B8 /* MASBrowserBasedAuthenticationInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = E0BA7849257E7FA60003A9B8 /* MASBrowserBasedAuthenticationInterface.h */; }; + E0BA7877257F708A0003A9B8 /* MASBrowserBasedAuthentication.m in Sources */ = {isa = PBXBuildFile; fileRef = C81CC3CB1FC2EA190058718E /* MASBrowserBasedAuthentication.m */; }; + E0BA788A257F78820003A9B8 /* MASBrowserBasedAuthenticationFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = E0BA7888257F78820003A9B8 /* MASBrowserBasedAuthenticationFactory.h */; }; + E0BA788B257F78820003A9B8 /* MASBrowserBasedAuthenticationFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = E0BA7889257F78820003A9B8 /* MASBrowserBasedAuthenticationFactory.m */; }; E3662A3723DEE503007A76A1 /* MASIHTTPRequestOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = E3662A3523DEE502007A76A1 /* MASIHTTPRequestOperation.h */; }; E3662A3823DEE503007A76A1 /* MASIHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = E3662A3623DEE502007A76A1 /* MASIHTTPRequestOperation.m */; }; E3662A3B23DEE52C007A76A1 /* MASIURLResponseSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = E3662A3923DEE52B007A76A1 /* MASIURLResponseSerialization.m */; }; @@ -687,6 +694,13 @@ CBD25B131E7A0A9200DFB47F /* MF_Base64Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MF_Base64Additions.m; sourceTree = ""; }; CBFA70F21F1ED5D6006D025D /* MASSecurityPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASSecurityPolicy.h; sourceTree = ""; }; CBFA70F31F1ED5D6006D025D /* MASSecurityPolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASSecurityPolicy.m; sourceTree = ""; }; + E0BA7849257E7FA60003A9B8 /* MASBrowserBasedAuthenticationInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MASBrowserBasedAuthenticationInterface.h; sourceTree = ""; }; + E0BA784A257E7FEF0003A9B8 /* MASSafariBrowserBasedAuthentication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MASSafariBrowserBasedAuthentication.h; sourceTree = ""; }; + E0BA784B257E7FEF0003A9B8 /* MASSafariBrowserBasedAuthentication.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MASSafariBrowserBasedAuthentication.m; sourceTree = ""; }; + E0BA785E257EB8C00003A9B8 /* MASWebSessionBrowserBasedAuthentication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MASWebSessionBrowserBasedAuthentication.h; sourceTree = ""; }; + E0BA785F257EB8C00003A9B8 /* MASWebSessionBrowserBasedAuthentication.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MASWebSessionBrowserBasedAuthentication.m; sourceTree = ""; }; + E0BA7888257F78820003A9B8 /* MASBrowserBasedAuthenticationFactory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MASBrowserBasedAuthenticationFactory.h; sourceTree = ""; }; + E0BA7889257F78820003A9B8 /* MASBrowserBasedAuthenticationFactory.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MASBrowserBasedAuthenticationFactory.m; sourceTree = ""; }; E3662A3523DEE502007A76A1 /* MASIHTTPRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASIHTTPRequestOperation.h; sourceTree = ""; }; E3662A3623DEE502007A76A1 /* MASIHTTPRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASIHTTPRequestOperation.m; sourceTree = ""; }; E3662A3923DEE52B007A76A1 /* MASIURLResponseSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASIURLResponseSerialization.m; sourceTree = ""; }; @@ -1122,6 +1136,13 @@ A898EF662182D35700CF291B /* MASJWKSet.m */, CBA3EB301E94634C00E64D9D /* MASClaims+MASPrivate.h */, CBA3EB311E94634C00E64D9D /* MASClaims+MASPrivate.m */, + E0BA7849257E7FA60003A9B8 /* MASBrowserBasedAuthenticationInterface.h */, + E0BA784A257E7FEF0003A9B8 /* MASSafariBrowserBasedAuthentication.h */, + E0BA784B257E7FEF0003A9B8 /* MASSafariBrowserBasedAuthentication.m */, + E0BA785E257EB8C00003A9B8 /* MASWebSessionBrowserBasedAuthentication.h */, + E0BA785F257EB8C00003A9B8 /* MASWebSessionBrowserBasedAuthentication.m */, + E0BA7888257F78820003A9B8 /* MASBrowserBasedAuthenticationFactory.h */, + E0BA7889257F78820003A9B8 /* MASBrowserBasedAuthenticationFactory.m */, ); path = models; sourceTree = ""; @@ -1493,15 +1514,18 @@ CB9B1207210949D5008A2075 /* NSMutableData+MASASN1Helper.h in Headers */, CBA3EB2E1E945F2400E64D9D /* MASClaims.h in Headers */, CB0B58591E258C2A00BC0163 /* MASAuthorizationResponse.h in Headers */, + E0BA786D257F62820003A9B8 /* MASBrowserBasedAuthenticationInterface.h in Headers */, CBA3EB321E94634C00E64D9D /* MASClaims+MASPrivate.h in Headers */, CBD25AFF1E78C47C00DFB47F /* JWTClaimsSetVerifier.h in Headers */, CBD25AF21E78C47C00DFB47F /* JWTRSAlgorithm.h in Headers */, CB6491F01FE9DAF300281288 /* MQTTPersistence.h in Headers */, 10E027A11F72B10100EAB103 /* RNCryptor+Private.h in Headers */, CBD25B0C1E78C47C00DFB47F /* JWTBase64Coder.h in Headers */, + E0BA788A257F78820003A9B8 /* MASBrowserBasedAuthenticationFactory.h in Headers */, A419B3A11C176259008DC88C /* NSData+MAS.h in Headers */, A488CE751C0B97FD00B8B961 /* MASService.h in Headers */, CB6491FB1FE9DAF300281288 /* MQTTSSLSecurityPolicy.h in Headers */, + E0BA7867257F62570003A9B8 /* MASSafariBrowserBasedAuthentication.h in Headers */, CBD25B0B1E78C47C00DFB47F /* JWT.h in Headers */, CBD25B091E78C47C00DFB47F /* JWTCoding.h in Headers */, CB6491F71FE9DAF300281288 /* MQTTSessionManager.h in Headers */, @@ -1523,6 +1547,7 @@ A4E340F91B9E9F2000883AD3 /* MAS.h in Headers */, E3662A4223DEE5A4007A76A1 /* MASINetworking.h in Headers */, CBD25AF31E78C47C00DFB47F /* JWTCryptoKey.h in Headers */, + E0BA7869257F62590003A9B8 /* MASWebSessionBrowserBasedAuthentication.h in Headers */, CB6492031FE9DAF300281288 /* MQTTStrict.h in Headers */, A4831AFD1BD1A917007B4AE6 /* MASUser+MASPrivate.h in Headers */, CBD25AEC1E78C47C00DFB47F /* JWTAlgorithmDataHolderChain.h in Headers */, @@ -1782,12 +1807,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + E0BA788B257F78820003A9B8 /* MASBrowserBasedAuthenticationFactory.m in Sources */, CB5E4C711C1D250D001B3B8A /* MASPutURLRequest.m in Sources */, CB2A4056209B9DA600F988AA /* MASMultiFactorHandler+MASPrivate.m in Sources */, A858C6661D0978A6001FB9AD /* MASOTPService.m in Sources */, CBD25AE71E78C47C00DFB47F /* JWTAlgorithmNone.m in Sources */, CB1C151F1E450109002B31A5 /* NSURL+MASPrivate.m in Sources */, 10D2D49F1C1686ED00DF8AC4 /* MASGroup+MASPrivate.m in Sources */, + E0BA7877257F708A0003A9B8 /* MASBrowserBasedAuthentication.m in Sources */, CB99754F1EDF5837006CEBB1 /* MASAuthCredentialsAuthorizationCode.m in Sources */, A488CE761C0B97FD00B8B961 /* MASService.m in Sources */, A42A86A11BBDA27F00AE98AC /* NSError+MASPrivate.m in Sources */, @@ -1799,6 +1826,7 @@ CB2357971F0EFDEA00D4C420 /* MASSessionTaskOperation.m in Sources */, CB6491E91FE9DAF300281288 /* MQTTDecoder.m in Sources */, CB64920A1FE9DAF300281288 /* ReconnectTimer.m in Sources */, + E0BA784D257E7FEF0003A9B8 /* MASSafariBrowserBasedAuthentication.m in Sources */, 10E027A01F72B10100EAB103 /* RNCryptor.m in Sources */, CBAFD24D1F2BD46C0034DF02 /* MASSecurityConfiguration.m in Sources */, CB6491E11FE9DAF300281288 /* MQTTCFSocketEncoder.m in Sources */, @@ -1826,6 +1854,7 @@ 10E027A71F72B10100EAB103 /* RNEncryptor.m in Sources */, 699570E72062FF1300017244 /* MASError.m in Sources */, CB9975571EDF5986006CEBB1 /* MASAuthCredentialsClientCredentials.m in Sources */, + E0BA7861257EB8C00003A9B8 /* MASWebSessionBrowserBasedAuthentication.m in Sources */, 5BD3E7E420630FC900A151C7 /* MASConstants.m in Sources */, A47332D01BBC61F50002A492 /* NSData+MASPrivate.m in Sources */, CBAFD2511F2BD48B0034DF02 /* MASSecurityConfiguration+MASPrivate.m in Sources */, @@ -1877,7 +1906,6 @@ CBD25AF61E78C47C00DFB47F /* JWTCryptoKeyExtractor.m in Sources */, A4150E701BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.m in Sources */, A417BA521BF033C300EC9BCB /* CLLocation+MASPrivate.m in Sources */, - C81CC3CD1FC2EA190058718E /* MASBrowserBasedAuthentication.m in Sources */, 69B7DF6D1F96756B0056DD3A /* MASRequest+MASPrivate.m in Sources */, A4831AB21BD1A551007B4AE6 /* MASFile.m in Sources */, CB0B585A1E258C2A00BC0163 /* MASAuthorizationResponse.m in Sources */, diff --git a/MASFoundation.xcodeproj/xcshareddata/xcschemes/MASFoundation.xcscheme b/MASFoundation.xcodeproj/xcshareddata/xcschemes/MASFoundation.xcscheme index 10f75bba..633e7556 100644 --- a/MASFoundation.xcodeproj/xcshareddata/xcschemes/MASFoundation.xcscheme +++ b/MASFoundation.xcodeproj/xcshareddata/xcschemes/MASFoundation.xcscheme @@ -41,6 +41,15 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -53,17 +62,6 @@ - - - - - - - - - - - - +#import "MASConstants.h" + +@protocol MASBrowserBasedAuthenticationInterface; + +/** + * Utility factory class to build the correct browser type to use + */ +@interface MASBrowserBasedAuthenticationFactory : NSObject + +/** + * Build a new browser used for Browser Based Authentication + * + * @param browserType MASBrowserBasedAuthenticationBrowserType object used to indicate type of browser built + * @return id object which can be used to start Browser Based Authentication. + */ ++ (id)buildBrowserOfBrowserType:(MASBrowserBasedAuthenticationBrowserType)browserType; + +@end diff --git a/MASFoundation/Classes/_private_/models/MASBrowserBasedAuthenticationFactory.m b/MASFoundation/Classes/_private_/models/MASBrowserBasedAuthenticationFactory.m new file mode 100644 index 00000000..8695d451 --- /dev/null +++ b/MASFoundation/Classes/_private_/models/MASBrowserBasedAuthenticationFactory.m @@ -0,0 +1,26 @@ +// +// MASBrowserBasedAuthenticationFactory.m +// MASFoundation +// +// Copyright (c) 2020 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// + +#import "MASBrowserBasedAuthenticationFactory.h" +#import "MASSafariBrowserBasedAuthentication.h" +#import "MASWebSessionBrowserBasedAuthentication.h" + +@implementation MASBrowserBasedAuthenticationFactory + ++ (id)buildBrowserOfBrowserType:(MASBrowserBasedAuthenticationBrowserType)browserType { + + switch (browserType) { + case MASBrowserBasedAuthenticationBrowserTypeSafari: + return [[MASSafariBrowserBasedAuthentication alloc] init]; + case MASBrowserBasedAuthenticationBrowserTypeWebSession: + return [[MASWebSessionBrowserBasedAuthentication alloc] init]; + } +} +@end diff --git a/MASFoundation/Classes/_private_/models/MASBrowserBasedAuthenticationInterface.h b/MASFoundation/Classes/_private_/models/MASBrowserBasedAuthenticationInterface.h new file mode 100644 index 00000000..ec821617 --- /dev/null +++ b/MASFoundation/Classes/_private_/models/MASBrowserBasedAuthenticationInterface.h @@ -0,0 +1,31 @@ +// +// MASBrowserBasedAuthenticationInterface.h +// MASFoundation +// +// Copyright (c) 2020 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// +#import "MASConstants.h" + +/** + * Interface used to abstract different type of browsers used for Browser Based Authentication + */ +@protocol MASBrowserBasedAuthenticationInterface + +/** + Starts the Browser based authentication with the given url and completion block. + + @param templatizedURL NSURL sent to the browser + @param completion MASAuthCredentialsBlock object. + */ +- (void)startWithURL:(NSURL *)templatizedURL completion:(MASAuthCredentialsBlock)webLoginBlock; + + +/** + Dismisses the currently presented browser. + */ +- (void)dismiss; + +@end diff --git a/MASFoundation/Classes/_private_/models/MASSafariBrowserBasedAuthentication.h b/MASFoundation/Classes/_private_/models/MASSafariBrowserBasedAuthentication.h new file mode 100644 index 00000000..bcdb7f2c --- /dev/null +++ b/MASFoundation/Classes/_private_/models/MASSafariBrowserBasedAuthentication.h @@ -0,0 +1,20 @@ +// +// MASSafariBrowserBasedAuthentication.h +// MASFoundation +// +// Copyright (c) 2020 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// + +#import + +@protocol MASBrowserBasedAuthenticationInterface; + +/** + * A Browser Based Authentication type utilising an SFSafarViewController + */ +@interface MASSafariBrowserBasedAuthentication : NSObject + +@end diff --git a/MASFoundation/Classes/_private_/models/MASSafariBrowserBasedAuthentication.m b/MASFoundation/Classes/_private_/models/MASSafariBrowserBasedAuthentication.m new file mode 100644 index 00000000..eaf693dd --- /dev/null +++ b/MASFoundation/Classes/_private_/models/MASSafariBrowserBasedAuthentication.m @@ -0,0 +1,86 @@ +// +// MASSafariBrowserBasedAuthentication.m +// MASFoundation +// +// Copyright (c) 2020 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// + +#import +#import "MASSafariBrowserBasedAuthentication.h" +#import "MASBrowserBasedAuthenticationInterface.h" +#import "UIAlertController+MAS.h" + +@interface MASSafariBrowserBasedAuthentication() + +///-------------------------------------- +/// @name Properties +///------------------------------------- + +# pragma mark - Properties + +@property (nonatomic, strong) SFSafariViewController *safariViewController; + + +@property (nonatomic, assign) MASAuthCredentialsBlock webLoginBlock; + +@end + + +@implementation MASSafariBrowserBasedAuthentication + +///-------------------------------------- +/// @name Start & Stop +///-------------------------------------- + +# pragma mark - Start & Stop + + +- (void)startWithURL:(NSURL *)url completion:(MASAuthCredentialsBlock)webLoginBlock +{ + self.safariViewController = [[SFSafariViewController alloc] initWithURL:url]; + self.safariViewController.delegate = self; + self.webLoginBlock = webLoginBlock; + + __weak MASSafariBrowserBasedAuthentication *weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + [UIAlertController rootViewController].modalTransitionStyle = UIModalTransitionStyleCoverVertical; + + [[UIAlertController rootViewController] presentViewController:weakSelf.safariViewController animated:YES completion:^{ + DLog(@"Successfully displayed login template"); + }]; + + return; + }); +} + + +- (void)dismiss +{ + __weak MASSafariBrowserBasedAuthentication *weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf.safariViewController dismissViewControllerAnimated:true completion: nil]; + }); + +} + + +///-------------------------------------- +/// @name SFSafariViewControllerDelegate +///-------------------------------------- + +#pragma mark - SFSafariViewControllerDelegate + +- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller { + self.webLoginBlock(nil, YES, ^(BOOL completed, NSError* error){ + if(error) + { + DLog(@"Browser cancel clicked"); + } + }); +} + +@end + diff --git a/MASFoundation/Classes/_private_/models/MASWebSessionBrowserBasedAuthentication.h b/MASFoundation/Classes/_private_/models/MASWebSessionBrowserBasedAuthentication.h new file mode 100644 index 00000000..cc09d194 --- /dev/null +++ b/MASFoundation/Classes/_private_/models/MASWebSessionBrowserBasedAuthentication.h @@ -0,0 +1,31 @@ +// +// MASWebSessionBrowserBasedAuthentication.h +// MASFoundation +// +// Copyright (c) 2020 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// + +#import + + + +NS_ASSUME_NONNULL_BEGIN + + + +@protocol MASBrowserBasedAuthenticationInterface; + +/** + * A Browser Based Authentication type utilising an ASWebAuthenticationSession + */ +API_AVAILABLE(ios(12.0), macCatalyst(13.0), macos(10.15), watchos(6.2)) +@interface MASWebSessionBrowserBasedAuthentication : NSObject + +@end + + + +NS_ASSUME_NONNULL_END diff --git a/MASFoundation/Classes/_private_/models/MASWebSessionBrowserBasedAuthentication.m b/MASFoundation/Classes/_private_/models/MASWebSessionBrowserBasedAuthentication.m new file mode 100644 index 00000000..112c5c2f --- /dev/null +++ b/MASFoundation/Classes/_private_/models/MASWebSessionBrowserBasedAuthentication.m @@ -0,0 +1,105 @@ +// +// MASWebSessionBrowserBasedAuthentication.m +// MASFoundation +// +// Copyright (c) 2020 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// + +#import "MASWebSessionBrowserBasedAuthentication.h" +#import +#import "MASBrowserBasedAuthenticationInterface.h" +#import "MASAuthorizationResponse.h" +#import "MASApplication+MASPrivate.h" + +API_AVAILABLE(ios(12.0), macCatalyst(13.0), macos(10.15), watchos(6.2)) +@interface MASWebSessionBrowserBasedAuthentication() + +///-------------------------------------- +/// @name Properties +///------------------------------------- + +# pragma mark - Properties + +@property (nonatomic, strong) ASWebAuthenticationSession *session; + + +@property (nonatomic, assign) MASAuthCredentialsBlock webLoginBlock; + + +@property (nonatomic, weak) id window; + + +@end + +API_AVAILABLE(ios(13.0), macos(10.15)) +@interface MASWebSessionBrowserBasedAuthentication() +@end + + +@implementation MASWebSessionBrowserBasedAuthentication + + +///-------------------------------------- +/// @name Start & Stop +///-------------------------------------- + +# pragma mark - Start & Stop + +- (void)startWithURL:(NSURL *)url completion:(MASAuthCredentialsBlock)webLoginBlock +{ + NSString *callbackURLScheme = [[MASApplication currentApplication].redirectUri absoluteString]; + + self.session = [[ASWebAuthenticationSession alloc] initWithURL:url callbackURLScheme:callbackURLScheme completionHandler:^(NSURL * _Nullable callbackURL, NSError * _Nullable error) { + if (callbackURL != nil) { + [MASAuthorizationResponse.sharedInstance handleAuthorizationResponseURL:callbackURL]; + } else { + webLoginBlock(nil, YES, ^(BOOL completed, NSError* error) { + if(error) + { + DLog("An error occured or the user pressed cancel") + } + }); + } + }]; + if (@available(iOS 13.0, macOS 10.15, *)) { + self.session.presentationContextProvider = self; + } + + __weak MASWebSessionBrowserBasedAuthentication* weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ +#if TARGET_OS_IOS + weakSelf.window = [[UIApplication sharedApplication] keyWindow]; +#else + weakSelf.window = [[NSApplication sharedApplication] keyWindow]; +#endif + if ([weakSelf.session start]) { + DLog(@"Successfully displayed login template"); + } + }); + +} + + +- (void)dismiss +{ + [self.session cancel]; +} + + + +///-------------------------------------- +/// @name ASWebAuthenticationPresentationContextProviding +///-------------------------------------- + +#pragma mark - ASWebAuthenticationPresentationContextProviding + +- (ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:(ASWebAuthenticationSession *)session { + return self.window; +} + +@end + + diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.h b/MASFoundation/Classes/_private_/services/model/MASModelService.h index 4e0c5abe..f88f55bd 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.h +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.h @@ -9,7 +9,6 @@ // #import "MASService.h" - #import "MASConstantsPrivate.h" @@ -101,6 +100,22 @@ + (BOOL)browserBasedAuthentication; +/** + * Sets the browser based authentication browser type + * + * @param browserType MASBrowserBasedAuthenticationBrowserType object indicating which type of browser to use when browser based authentication is used. + */ ++ (void)setBrowserBasedAuthenticationBrowserType:(MASBrowserBasedAuthenticationBrowserType)browserType; + + +/** + * The current browser based authentication browser type. + * + * @return MASBrowserBasedAuthenticationBrowserType object is returned. + */ ++ (MASBrowserBasedAuthenticationBrowserType)browserBasedAuthenticationBrowserType; + + ///-------------------------------------- /// @name Application ///-------------------------------------- diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.m b/MASFoundation/Classes/_private_/services/model/MASModelService.m index ebad3efa..6562bef5 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.m +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.m @@ -11,6 +11,7 @@ #import "MASModelService.h" #import "MASAccessService.h" #import "MASConfigurationService.h" +#import "MASConstants.h" #import "MASFileService.h" #import "MASSecurityService.h" #import "MASServiceRegistry.h" @@ -40,6 +41,7 @@ @implementation MASModelService static MASGrantFlow _grantFlow_ = MASGrantFlowClientCredentials; static MASUserAuthCredentialsBlock _userAuthCredentialsBlock_ = nil; static BOOL _isBrowserBasedAuthentication_ = NO; +static MASBrowserBasedAuthenticationBrowserType _browserBasedAuthenticationBrowserType_ = MASBrowserBasedAuthenticationBrowserTypeSafari; # pragma mark - Properties @@ -85,6 +87,18 @@ + (BOOL)browserBasedAuthentication } ++ (void)setBrowserBasedAuthenticationBrowserType:(MASBrowserBasedAuthenticationBrowserType)browserType +{ + _browserBasedAuthenticationBrowserType_ = browserType; +} + + ++ (MASBrowserBasedAuthenticationBrowserType)browserBasedAuthenticationBrowserType +{ + return _browserBasedAuthenticationBrowserType_; +} + + # pragma mark - Shared Service + (instancetype)sharedService diff --git a/MASFoundation/Classes/models/MASAuthorizationResponse.h b/MASFoundation/Classes/models/MASAuthorizationResponse.h index 1aeb77f7..9dbc4bb8 100644 --- a/MASFoundation/Classes/models/MASAuthorizationResponse.h +++ b/MASFoundation/Classes/models/MASAuthorizationResponse.h @@ -87,7 +87,7 @@ NS_ASSUME_NONNULL_BEGIN #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_9_3 /** - * Prase returned URL from SFSafariViewController with authorization code and OAuth state. + * Prase returned URL from Browser Based Authentication with authorization code and OAuth state. * Call this method inside [UIApplicationDelegate application:openURL:options:] of the AppDelegate for the application. * This method should be invoked in order to properly perform social login in MASFoundation SDK. * @@ -103,7 +103,7 @@ NS_ASSUME_NONNULL_BEGIN /** - * Prase returned URL from SFSafariViewController with authorization code and OAuth state. + * Prase returned URL from Browser Based Authentication with authorization code and OAuth state. * Call this method inside [UIApplicationDelegate application:openURL:sourceApplication:annotation:] of the AppDelegate for the application. * This method should be invoked in order to properly perform social login in MASFoundation SDK. * @@ -116,6 +116,18 @@ NS_ASSUME_NONNULL_BEGIN */ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; + +/** + * Prase returned URL from Browser Based Authentication with authorization code and OAuth state. + * Call this method inside [UIApplicationDelegate application:openURL:sourceApplication:annotation:] of the AppDelegate for the application. + * This method should be invoked in order to properly perform social login in MASFoundation SDK. + * + * @param url NSURL object as passed in [UIApplicationDelegate application:openURL:sourceApplication:annotation:]. + * + * @return BOOL value whether the URL is specific for social login in MASFoundation or not. + */ +- (BOOL)handleAuthorizationResponseURL:(NSURL *)url; + NS_ASSUME_NONNULL_END @end diff --git a/MASFoundation/Classes/models/MASAuthorizationResponse.m b/MASFoundation/Classes/models/MASAuthorizationResponse.m index abe3cebb..d547ecea 100644 --- a/MASFoundation/Classes/models/MASAuthorizationResponse.m +++ b/MASFoundation/Classes/models/MASAuthorizationResponse.m @@ -70,6 +70,12 @@ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceAppl } +- (BOOL)handleAuthorizationResponseURL:(NSURL *)url +{ + return [self validateURLForAuthorizationURL:url]; +} + + # pragma mark - Private - (BOOL)validateURLForAuthorizationURL:(NSURL *)url diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m index a10e97f2..8f1510eb 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m @@ -14,6 +14,8 @@ #import "MASConfigurationService.h" #import "MASGetURLRequest.h" #import "MASModelService.h" +#import "MASBrowserBasedAuthenticationFactory.h" +#import "MASBrowserBasedAuthenticationInterface.h" #import "UIAlertController+MAS.h" #import @@ -22,7 +24,7 @@ @interface MASBrowserBasedAuthentication () browser; @property (nonatomic) MASAuthCredentialsBlock webLoginCallBack; @end @@ -162,18 +164,18 @@ - (void)getURLForWebLogin // This get request would result in a redirection which contains the actual URL to be loaded into browser and hence this would be canceled after the redirection // [[MASNetworkingService sharedService] getFrom:endPoint withParameters:parameterInfo andHeaders:headerInfo requestType:MASRequestResponseTypeWwwFormUrlEncoded responseType:MASRequestResponseTypeWwwFormUrlEncoded completion:^(NSDictionary* response, NSError* error){ - - // - // We expect this API to be cancelled in the redirection and hence the only acceptable error here is cancel.Any other error could mean an error for authenticaion itself. Hence cancel authorization. - // - if(error.code != NSURLErrorCancelled) - { - DLog(@"error occured in BBA error info: %@",error); - blockSelf.webLoginCallBack(nil, YES, nil); - return; - } - - [[MASNetworkingService sharedService] setHttpRedirectionBlock:previousRedirectionBlock]; + + // + // We expect this API to be cancelled in the redirection and hence the only acceptable error here is cancel.Any other error could mean an error for authenticaion itself. Hence cancel authorization. + // + if(error.code != NSURLErrorCancelled) + { + DLog(@"error occured in BBA error info: %@",error); + blockSelf.webLoginCallBack(nil, YES, nil); + return; + } + + [[MASNetworkingService sharedService] setHttpRedirectionBlock:previousRedirectionBlock]; }]; } @@ -181,22 +183,22 @@ - (MASSessionDataTaskHTTPRedirectBlock)getRedirectionBlock { __block MASBrowserBasedAuthentication *blockSelf = self; MASSessionDataTaskHTTPRedirectBlock redirectionBlock = ^(NSURLSession *session, NSURLSessionTask *task, NSURLResponse * response, NSURLRequest *request){ - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; - if(httpResponse.statusCode == 302 && [self isBBARedirection:task.originalRequest]) + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + if(httpResponse.statusCode == 302 && [self isBBARedirection:task.originalRequest]) + { + DLog(@"all headers %@",httpResponse.allHeaderFields); + NSString* locationURL = [httpResponse.allHeaderFields objectForKey:@"Location"]; + NSURL* redirectURL = [NSURL URLWithString:locationURL]; + [task cancel]; + + if(![blockSelf redirectURLHasErrors:redirectURL]) { - DLog(@"all headers %@",httpResponse.allHeaderFields); - NSString* locationURL = [httpResponse.allHeaderFields objectForKey:@"Location"]; - NSURL* redirectURL = [NSURL URLWithString:locationURL]; - [task cancel]; - - if(![blockSelf redirectURLHasErrors:redirectURL]) - { - [blockSelf launchBrowserWithURL:redirectURL]; - } - else{ - blockSelf.webLoginCallBack(nil, YES, nil); - } + [blockSelf launchBrowserWithURL:redirectURL]; } + else{ + blockSelf.webLoginCallBack(nil, YES, nil); + } + } //return a nil request as we would have already cancelled the request //return a nil as compiler expects a NSURLRequest object NSURLRequest* nilRequest = nil; @@ -230,35 +232,9 @@ - (BOOL)redirectURLHasErrors :(NSURL*)redirectURL - (void)launchBrowserWithURL:(NSURL*)templatizedURL { - __block MASBrowserBasedAuthentication *blockSelf = self; - __weak __typeof__(self) weakSelf = self; - blockSelf.safariViewController = [[SFSafariViewController alloc] initWithURL:templatizedURL]; - blockSelf.safariViewController.delegate = weakSelf; - - dispatch_async(dispatch_get_main_queue(), ^{ - [UIAlertController rootViewController].modalTransitionStyle = UIModalTransitionStyleCoverVertical; - - [[UIAlertController rootViewController] presentViewController:blockSelf.safariViewController animated:YES - completion:^{ - - DLog(@"Successfully displayed login template"); - }]; - - return; - }); -} - - -#pragma mark - SafariViewController Delegates - -- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller -{ - self.webLoginCallBack(nil, YES, ^(BOOL completed, NSError* error){ - if(error) - { - DLog(@"Browser cancel clicked"); - } - }); + MASBrowserBasedAuthenticationBrowserType browserType = [MASModelService browserBasedAuthenticationBrowserType]; + self.browser = [MASBrowserBasedAuthenticationFactory buildBrowserOfBrowserType:browserType]; + [self.browser startWithURL:templatizedURL completion: self.webLoginCallBack]; } @@ -298,7 +274,7 @@ - (void)didReceiveError:(NSError *)error - (void)dismissBrowser { dispatch_async(dispatch_get_main_queue(), ^{ - [[UIAlertController rootViewController] dismissViewControllerAnimated:YES completion:nil]; + [self.browser dismiss]; }); } diff --git a/MASFoundation/Classes/models/MFA/MASMultiFactorHandler.h b/MASFoundation/Classes/models/MFA/MASMultiFactorHandler.h index 5e9ace76..46a2a146 100644 --- a/MASFoundation/Classes/models/MFA/MASMultiFactorHandler.h +++ b/MASFoundation/Classes/models/MFA/MASMultiFactorHandler.h @@ -49,7 +49,7 @@ @return nil will always be returned with this initialization method. */ -- (instancetype _Nullable)init NS_UNAVAILABLE; +- (instancetype _Null_unspecified)init NS_UNAVAILABLE; @@ -58,7 +58,7 @@ @return nil will always be returned with this initialization method. */ -+ (instancetype _Nullable)new NS_UNAVAILABLE; ++ (instancetype _Null_unspecified)new NS_UNAVAILABLE;